package Dynamic_Programming;
/*
* 给定一个整数 n，求以 1 ... n 为节点组成的二叉搜索树有多少种？
*
* 确定dp数组（dp table）以及下标的含义
    dp[i]为i个数字组成的二叉搜索树
确定递推公式
    dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]
    j相当于是头结点的元素，从1遍历到i为止。
    所以递推公式：dp[i] += dp[j - 1] * dp[i - j]; ，j-1 为j为头结点左子树节点数量，i-j 为以j为头结点右子树节点数量
dp数组如何初始化
    dp[1]=1
    dp[2]=2
    dp[3]=5
确定遍历顺序
举例推导dp数组
*
* */
public class lc96 {
    public static void main(String[] args) {
        Integer a=100;
        Integer b =new Integer(100);
        System.out.println(a==b);
        System.out.println(b==100);
    }
    public int numTrees(int n) {
        //初始化 dp 数组
        int[] dp = new int[n + 1];
        //初始化0个节点和1个节点的情况
        dp[0] = 1;
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            for (int j = 1; j <= i; j++) {
                //对于第i个节点，需要考虑1作为根节点直到i作为根节点的情况，所以需要累加
                //一共i个节点，对于根节点j时,左子树的节点个数为j-1，右子树的节点个数为i-j
                dp[i] += dp[j - 1] * dp[i - j];
            }
        }
        return dp[n];
    }
}
